package ar.edu.unicen.exa.isistan.archassis.diff;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import jdiff.API;
import jdiff.APIComparator;
import jdiff.JDiffAntTask.ProjectInfo;
import jdiff.XMLToAPI;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.DirSet;

import ar.edu.unicen.exa.isistan.archassis.DiffRequestData;
import ar.edu.unicen.exa.isistan.archassis.actions.IAction;
import ar.edu.unicen.exa.isistan.archassis.metadata.ClassResolver;
import ar.edu.unicen.exa.isistan.archassis.rcs.IVersion;
import ar.edu.unicen.exa.isistan.archassis.util.MiscUtils;

public class JavaDiffFacade {
	private static String VERSION_A = "VersionA";
	private static String VERSION_B = "VersionB";

	private static APIComparator compare(File dest) {
		System.out.println("compare!");
		File tempOldFileName = new File(dest, VERSION_A + ".xml");
		File tempNewFileName = new File(dest, VERSION_B + ".xml");

		System.out.println("JDiff: reading the old API in from file '"
				+ tempOldFileName + "'...");
		API oldAPI = XMLToAPI.readFile(tempOldFileName.getAbsolutePath(),
				false, VERSION_A);

		// Read the file where the XML representing the new API is stored
		// and create an API object for it.
		System.out.println("JDiff: reading the new API in from file '"
				+ tempNewFileName + "'...");
		// Read the file in, and do add any text to the global comments
		API newAPI = XMLToAPI.readFile(tempNewFileName.getAbsolutePath(), true,
				VERSION_B);

		// Compare the old and new APIs.
		APIComparator comp = new APIComparator();

		comp.compareAPIs(oldAPI, newAPI);

		return comp;
	}

	private static boolean deleteDirectory(File path) {
		if (path.exists()) {
			File[] files = path.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					deleteDirectory(files[i]);
				} else {
					files[i].delete();
				}
			}
		}
		// return( path.delete() );
		return true;
	}

	private static void diff(File v1Dir, File v2Dir, File dest) {
		deleteDirectory(dest);
		JDiffData data = new JDiffData();
		data.setStats(true);
		data.setDocchanges(true);

		{
			DirSet newDirSet = new DirSet();
			newDirSet.setDir(v1Dir);
			ProjectInfo newProjectInfo = new ProjectInfo();
			newProjectInfo.setDirset(newDirSet);
			newProjectInfo.setName(VERSION_A);
			data.addConfiguredNew(newProjectInfo);
		}

		{
			DirSet oldDirSet = new DirSet();
			oldDirSet.setDir(v2Dir);
			ProjectInfo oldProjectInfo = new ProjectInfo();
			oldProjectInfo.setDirset(oldDirSet);
			oldProjectInfo.setName(VERSION_B);
			data.addConfiguredOld(oldProjectInfo);
		}
		data.setDestdir(dest);
		Project project = new Project();
		data.setProject(project);
		try {
			JDiffExecute.execute(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static APIComparator compareAPI(DiffRequestData tempFile, String srcRelativePath,
			IVersion v1, IVersion v2) {

		File v1Dir = new File(tempFile.getDestinationFor(v1), srcRelativePath);
		File v2Dir = new File(tempFile.getDestinationFor(v2), srcRelativePath);
		
		MiscUtils.createNullClass(v1Dir);
		MiscUtils.createNullClass(v2Dir);
		// String srcFolders = ClassResolver.getInstance().getSrcFolders();
		diff(v1Dir, v2Dir, tempFile.getDiffTempDir());

		return compare(tempFile.getDiffTempDir());
	}

	public static List<IAction> compare(DiffRequestData tempFile, IVersion v1, IVersion v2, ClassResolver classResolver) {
		//ClassResolver classResolver = new ClassResolver(tempFile.getDestinationFor(v1),tempFile.getDestinationFor(v2));
		List<IAction> result = new ArrayList<IAction>();
		
		for (String srcRelativePath : classResolver.getSrcFolders()) {
		
			APIComparator apiComparator = compareAPI(tempFile, srcRelativePath, v1, v2);
			List<IAction> list = JavaDiffAdapter.process(apiComparator);
			result.addAll(list);
		}
		return result;
	}
}
